Estoy tratando de hacer coincidir [abc] a menos que esté "escapado" por [] de ambos lados (por lo que [[abc]] se considera escapado, pero no [[abc] o [abc]] ).
Lo más cercano que pude encontrar es (?<!\[)\[abc\](?!\]) de Match "ABC" de *ABC*, pero no de **ABC** , pero ignora la coincidencia si se escapa de un solo lado.
La anticipación podría estar a la izquierda o a la derecha para permitir un solo backet a la izquierda o a la derecha, pero no un corchete doble en el otro lado.
(?<!\[)\[abc]|\[abc](?!])La respuesta de @Thefourthbird funciona, pero requeriría que se repita el patrón principal abc , lo que va en contra del principio SECO que se recomienda a la mayoría seguir.
Con el interés de maximizar la reutilización del código, un enfoque sería usar un grupo de captura para capturar [abc] y luego usarlo en un patrón de búsqueda negativa para asegurarse de que no esté precedido por un [ y seguido por un ] :
(\[abc])(?<!\[\1(?=]))Tenga en cuenta que esto funciona para C# porque .NET admite patrones de búsqueda posterior de longitud variable, que no son compatibles con muchos otros motores de expresiones regulares.